package com.ccrfid.rmc6.service.device;

import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.device.LocatorEntity;
import com.ccrfid.rmc6.repository.device.LocatorRepository;
import com.ccrfid.rmc6.repository.search.SearchCriteria;
import com.ccrfid.rmc6.resource.device.pojo.FloorPos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.ws.rs.core.Response;
import java.util.List;

@Service
@Transactional
public class LocatorServiceImpl implements LocatorService {
    private static final Logger logger = LoggerFactory.getLogger(LocatorServiceImpl.class);
    @Autowired
    private LocatorRepository locatorRepository;

    @Override
    public Page<LocatorEntity> getLocatorInfoPage(SearchCriteria criteria, Pageable pageable) {
        Page<LocatorEntity> page = locatorRepository.search(criteria, pageable);
        return page;
    }

    @Override
    public List<LocatorEntity> getLocatorList(SearchCriteria criteria, Sort sort) {
        return locatorRepository.search(criteria, sort);
    }

    @Override
    public List<LocatorEntity> getAllLocators() {
        return locatorRepository.getAllBy();
    }

    @Override
    public LocatorEntity getLocator(Long locatorId) {
        return locatorRepository.getById(locatorId);
    }

    @Override
    public LocatorEntity getLocatorByLocatorAddress(Integer locatorAddress) {
        return locatorRepository.getByLocatorAddress(locatorAddress);
    }

    @Override
    public LocatorEntity createLocator(LocatorEntity entity) throws AppException {
        checkCreateParam(entity);
        return locatorRepository.save(entity);
    }

    private void checkCreateParam(LocatorEntity entity) throws AppException {
        if (locatorRepository.existsByLocatorAddress(entity.getLocatorAddress())) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.locator_address_conflict.getCode(), CustomErrors.locator_address_conflict.getReason(), "");
        }
        if (entity.getSn() != null && locatorRepository.existsBySn(entity.getSn())) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.sn_conflict.getCode(), CustomErrors.sn_conflict.getReason(), "");
        }
    }

    @Override
    public LocatorEntity updateLocator(Long locatorId, LocatorEntity entity) throws AppException {
        checkUpdateParam(locatorId, entity);
        return locatorRepository.save(entity);
    }

    private void checkUpdateParam(Long locatorId, LocatorEntity entity) throws AppException {
        if (!locatorId.equals(entity.getId())) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.different_args.getCode(), CustomErrors.different_args.getReason(), "");
        }
        if (!locatorRepository.existsById(locatorId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        if (locatorRepository.existsByLocatorAddressAndIdNot(entity.getLocatorAddress(), locatorId)) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.locator_address_conflict.getCode(), CustomErrors.locator_address_conflict.getReason(), "");
        }
        if (entity.getSn() != null && locatorRepository.existsBySnAndIdNot(entity.getSn(), locatorId)) {
            throw new AppException(Response.Status.CONFLICT.getStatusCode(),
                    CustomErrors.sn_conflict.getCode(), CustomErrors.sn_conflict.getReason(), "");
        }
    }

    @Override
    public void updateOnlineStatus(Integer locatorAddress, Integer onlineStatus) {
        LocatorEntity locatorEntity = locatorRepository.getByLocatorAddress(locatorAddress);
        if (locatorEntity != null) {
            locatorEntity.setOnlineStatus(onlineStatus);
            locatorRepository.save(locatorEntity);
        }
    }

    @Override
    public LocatorEntity updatePosition(Long locatorId, FloorPos floorPos) throws AppException {
        if (!locatorRepository.existsById(locatorId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        LocatorEntity locatorEntity = locatorRepository.getById(locatorId);
        if (locatorEntity != null) {
            locatorEntity.setFloorNumber(floorPos.getFloorNumber());
            locatorEntity.setPos(floorPos.getPos());
            locatorRepository.save(locatorEntity);
        }
        return locatorEntity;
    }

    @Override
    public LocatorEntity deletePosition(Long locatorId) throws AppException {
        if (!locatorRepository.existsById(locatorId)) {
            throw new AppException(Response.Status.NOT_FOUND.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        LocatorEntity locatorEntity = locatorRepository.getById(locatorId);
        if (locatorEntity != null) {
            locatorEntity.setFloorNumber(null);
            locatorEntity.setPos(null);
            locatorRepository.save(locatorEntity);
        }
        return locatorEntity;
    }

    @Override
    public int deleteLocatorsInfo(List<Long> idList) {
        int count = 0;
        for (Long id : idList) {
            if (locatorRepository.existsById(id)) {
                count++;
            }
        }
        if (count > 0) {
            //删除定位器信息
            locatorRepository.deleteByIdIn(idList);
        }
        return count;
    }
}
